using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace GetTogether.Studio.Windows
{
    public partial class FormSchedule : Form
    {
        public FormSchedule()
        {
            InitializeComponent();
        }

        string schedule_url = string.Concat(Config.Original.WorkStudioUrl, "Schedule/?from-schedule=1&show=1");
        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
                ScheduleSvc.Url = string.Concat(Config.Original.WorkStudioUrl, "API/ScheduleService.asmx");
                WebBrowserScheduleTask.Url = new Uri(schedule_url);
                LabelTaskName.Text = "";
            }
            catch (Exception ex)
            {
                Error(ex, "");
            }
        }
        void Error(Exception ex, string appendMsg)
        {
            RichTextBoxConsoleLogs.Text += string.Concat(string.IsNullOrEmpty(appendMsg) ? "" : string.Concat(appendMsg, "\r\n"), ex.ToString(), "\r\n-----------------------------------------------------------------------------\r\n");
        }
        const string AppendParameter = "from-schedule=1";
        Schedule.ScheduleService ScheduleSvc = new GetTogether.Studio.Windows.Schedule.ScheduleService();
        Dictionary<string, string> InvokedResults = new Dictionary<string, string>();
        private void ScheduleTaskTimer_Tick(object sender, EventArgs e)
        {
            ScheduleTaskTimer.Enabled = false;
            try
            {
                List<string> ivScheduleNames = new List<string>();
                foreach (string ivName in listBoxInvoking.Items)
                {
                    string[] ivNameInfo = ivName.Split(new string[] { " -> " }, StringSplitOptions.None);
                    if (ivNameInfo.Length > 0)
                        ivScheduleNames.Add(ivNameInfo[0]);
                }
                if (ivScheduleNames.Count > 0)
                {
                    Console.WriteLine("Invokings:");
                    foreach (string scheduleName in ivScheduleNames)
                    {
                        Console.WriteLine(scheduleName);
                    }
                }
                GetTogether.Studio.Windows.Schedule.ScheduleTask[] schedules = ScheduleSvc.GetSchedules(ivScheduleNames.ToArray());
                Console.WriteLine("Schedules:" + schedules.Length);
                if (schedules != null && schedules.Length > 0)
                {
                    foreach (GetTogether.Studio.Windows.Schedule.ScheduleTask s in schedules)
                    {
                        Console.WriteLine(s.Name);
                        new System.Threading.Thread(delegate()
                       {
                           string scheduleInfo = string.Format("{0} -> Week:{1}, Time:{2}, Action On:{3}",
                               s.Name,
                               GetTogether.Utility.DateHelper.GetWeekdayString(s.Week),
                               string.Concat(s.Date, (!string.IsNullOrEmpty(s.Date) ? " " : ""), s.Time, s.RepeatForTime ? "(Repeat)" : ""),
                               DateTime.Now.ToString());
                           string fileName = string.Concat(s.Name, DateTime.Now.ToString("_yyyy-MM-dd HH ss mm"), new Random().Next(), ".txt");
                           InvokedResults[scheduleInfo] = fileName;
                           string schName = s.Name;
                           string error = string.Empty;
                           string url = string.Empty;
                           try
                           {
                               GetTogether.Net.Extension.WebClient wc = new GetTogether.Net.Extension.WebClient();
                               wc.Timeout = int.MaxValue / 1000;
                               wc.Encoding = System.Text.Encoding.UTF8;
                               url = s.Url;
                               url = string.Concat(url, ((url.IndexOf("?") < 0) ? "?" : "&"), AppendParameter);
                               listBoxInvoking.Items.Add(scheduleInfo);
                               SaveLog(InvokedResults[scheduleInfo], wc.DownloadString(url));
                           }
                           catch (Exception ex)
                           {
                               error = string.Concat(url, "\r\n", ex.ToString());
                               SaveLog(InvokedResults[scheduleInfo], error);
                               Error(ex, url);
                           }
                           listBoxInvoking.Items.Remove(scheduleInfo);
                           ScheduleSvc.UpdateSchedule(schName, error, ReadLog(InvokedResults[scheduleInfo]));
                           ListBoxExcutedTask.Items.Add(scheduleInfo);
                           if (ListBoxExcutedTask.Items.Count > 1000)
                           {
                               string key = (string)ListBoxExcutedTask.Items[0];
                               if (InvokedResults.ContainsKey(key)) InvokedResults.Remove(key);
                               ListBoxExcutedTask.Items.RemoveAt(0);
                           }
                       }).Start();
                        System.Threading.Thread.Sleep(500);
                    }
                    ScheduleTaskTimer.Interval = 1000;
                }
                else
                {
                    ScheduleTaskTimer.Interval = 10000;
                }
            }
            catch (Exception ex)
            {
                Error(ex, "");
            }
            finally
            {
                ScheduleTaskTimer.Enabled = true;
            }
        }
        private string GetFilePath(string fileName)
        {
            string dir = System.IO.Path.Combine(Application.StartupPath, "Logs");
            if (!System.IO.Directory.Exists(dir)) System.IO.Directory.CreateDirectory(dir);
            return string.Concat(dir, "\\", fileName);
        }
        private void SaveLog(string fileName, string log)
        {
            System.IO.File.WriteAllText(GetFilePath(fileName), log);
        }
        private string ReadLog(string fileName)
        {
            return System.IO.File.ReadAllText(GetFilePath(fileName), System.Text.Encoding.UTF8);
        }
        private void DeleteLog(string fileName)
        {
            string path = GetFilePath(fileName);
            if (System.IO.File.Exists(path))
                System.IO.File.Delete(path);
        }
        private void ListBoxExcutedTask_Click(object sender, EventArgs e)
        {
            try
            {
                ListBox lb = (ListBox)sender;

                if (lb.SelectedIndex >= 0)
                {
                    string selectedKey = (string)lb.Items[lb.SelectedIndex];
                    if (InvokedResults.ContainsKey(selectedKey)) richTextBoxTaskViewer.Text = ReadLog(InvokedResults[selectedKey]);
                    LabelTaskName.Text = string.Concat(" : ", (string)lb.Items[lb.SelectedIndex]);
                }
            }
            catch (Exception ex)
            {
                Error(ex, "");
            }
        }

        private void ListBoxExcutedTask_KeyDown(object sender, KeyEventArgs e)
        {
            try
            {
                ListBox lb = (ListBox)sender;
                if (e.KeyValue == 46 && lb.SelectedIndex >= 0)
                {
                    int oldSelectedIndex = lb.SelectedIndex;
                    string selectedKey = (string)lb.Items[lb.SelectedIndex];
                    DeleteLog(InvokedResults[selectedKey]);
                    if (InvokedResults.ContainsKey(selectedKey))
                    {
                        InvokedResults.Remove(selectedKey);
                    }
                    ListBoxExcutedTask.Items.RemoveAt(lb.SelectedIndex);
                    if (ListBoxExcutedTask.Items.Count > 0)
                    {
                        if (oldSelectedIndex == 0)
                        {
                            ListBoxExcutedTask.SelectedIndex = 0;
                        }
                        else if (oldSelectedIndex >= ListBoxExcutedTask.Items.Count)
                        {
                            ListBoxExcutedTask.SelectedIndex = oldSelectedIndex - 1;
                        }
                        else if (oldSelectedIndex < ListBoxExcutedTask.Items.Count)
                        {
                            ListBoxExcutedTask.SelectedIndex = oldSelectedIndex;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Error(ex, "");
            }
        }

        private void FormSchedule_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                ScheduleTaskTimer.Enabled = false;
                List<string> ivScheduleNames = new List<string>();
                foreach (string ivName in listBoxInvoking.Items)
                {
                    string[] ivNameInfo = ivName.Split(new string[] { " -> " }, StringSplitOptions.None);
                    if (ivNameInfo.Length > 0)
                        ivScheduleNames.Add(ivNameInfo[0]);
                }
                foreach (string scheduleName in ivScheduleNames)
                {
                    ScheduleSvc.UpdateSchedule(scheduleName, "Thread was closed on program closing.", "-");
                }
                Application.ExitThread();
            }
            catch (Exception ex)
            {
                Error(ex, "");
            }
        }
    }
}